package com.cloud.bc.controller.ajax;

import cn.hutool.core.convert.Convert;
import cn.hutool.core.net.Ipv4Util;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.cloud.bc.config.Config;
import com.cloud.bc.model.domain.UserInfo;
import com.cloud.bc.model.entity.*;
import com.cloud.bc.model.enums.CookieConst;
import com.cloud.bc.model.enums.RedisKey;
import com.cloud.bc.model.request.LoginRequest;
import com.cloud.bc.model.request.RegisterReq;
import com.cloud.bc.model.request.UserCodeRequest;
import com.cloud.bc.model.response.AjaxResp;
import com.cloud.bc.service.*;
import com.cloud.bc.util.BcEmailUtil;
import com.cloud.bc.util.BcSmsUtil;
import com.cloud.common.model.enums.MailTemplatesEnum;
import com.cloud.common.model.enums.SmsTemplatesEnum;
import com.cloud.common.security.AES;
import com.cloud.common.security.AESUtil;
import com.cloud.common.util.CookieUtils;
import com.cloud.common.util.IpUtils;
import com.cloud.redis.config.RedisUtils;
import com.google.zxing.client.result.SMSMMSResultParser;
import lombok.AllArgsConstructor;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Date;
import java.util.List;
import java.util.concurrent.TimeUnit;

@AllArgsConstructor
@RestController
@RequestMapping("m/ajax/user")
public class Ajax_MUserController {

    private final BcUsersService bcUsersService;
    private final BcSinglesService bcSinglesService;
    private final BcSingleMatesService bcSingleMatesService;
    private final BcAuthenticationsService bcAuthenticationsService;
    private final BcSingleContactsService bcSingleContactsService;
    private final Config config;
    private final BcEmailUtil bcEmailUtil;
    private final RedisUtils redisUtils;
    private final BcSmsUtil bcSmsUtil;

    @PostMapping("register")
    public AjaxResp register(
            HttpServletRequest request,
            HttpServletResponse response,
            RegisterReq req) {
        AjaxResp ajaxResp = new AjaxResp();
        BcUsers bcUsers = new BcUsers();
        if (req.getWay().equals("email")) {
            //验证邮件码
            String regRedisKey = RedisKey.bcSingleRegRedisKey + req.getEmail();
            Object regCode = redisUtils.get(regRedisKey);
            if (regCode == null || !Convert.toStr(regCode).equals(req.getEmailyzm())) {
                ajaxResp.setSuccess(false);
                ajaxResp.setMsg("邮件验证码输入错误");
                return ajaxResp;
            }
            bcUsers.setEmail(req.getEmail());
        }
        if (req.getWay().equals("mobile")) {
            String regRedisKey = RedisKey.bcSingleRegRedisKey + req.getMobile();
            Object regCode = redisUtils.get(regRedisKey);
            if (regCode == null || !Convert.toStr(regCode).equals(req.getSmsyzm())) {
                ajaxResp.setSuccess(false);
                ajaxResp.setMsg("手机验证码输入错误");
                return ajaxResp;
            }
            bcUsers.setMobile(req.getMobile());
        }
        int count = bcUsersService.count(bcUsers);
        if (count > 0) {
            ajaxResp.setSuccess(false);
            ajaxResp.setMsg("账号已经注册了");
            return ajaxResp;
        }
        if (!StrUtil.isEmpty(req.getOpenid())) {
            String openid = AESUtil.decrypt(req.getOpenid(), config.getOpenidSecret());
            Integer oId = Convert.toInt(openid, 0);
            //判断一下，如果当前openid已经存在就不能再绑定了
            if (bcUsersService.count(new BcUsers().setOpenid(oId)) > 0) {
                ajaxResp.setSuccess(false);
                ajaxResp.setMsg("当前微信已经绑定过账户");
                return ajaxResp;
            }
            //绑定openid
            bcUsers.setOpenid(oId);
        }
        if (StrUtil.isNotEmpty(req.getPassword())) {
            bcUsers.setPassword(AES.aesEncrypt(req.getPassword()));
        }
        bcUsers.setRegip(IpUtils.getIpAddr(request));
        bcUsersService.save(bcUsers);
        Integer id = bcUsers.getId();

        BcSingles bcSingles = new BcSingles();
        bcSingles.setUserId(id);
        //设置user_eid属性
        setEid(request, response, bcSingles);
        //单身表
        bcSinglesService.save(bcSingles);
        BcSingleMates bcSingleMates = new BcSingleMates();
        bcSingleMates.setUserId(id);
        //择偶表
        bcSingleMatesService.save(bcSingleMates);
        BcAuthentications bcAuthentications = new BcAuthentications();
        bcAuthentications.setUserId(id);
        //认证表
        bcAuthenticationsService.save(bcAuthentications);
        BcSingleContacts bcSingleContacts = new BcSingleContacts();
        bcSingleContacts.setUserId(id);
        bcSingleContactsService.save(bcSingleContacts);
        ajaxResp.setCode(301);
        String targetUrl = "/m/login";
        if (StrUtil.isNotEmpty(req.getSource()) && req.getSource().contains("pc")) {
            targetUrl = "/login";
        }
        ajaxResp.setObj(targetUrl);
        ajaxResp.setMsg("注册成功");
        return ajaxResp;
    }

    /**
     * 设置user_eid属性
     */
    private void setEid(HttpServletRequest request,
                        HttpServletResponse response,
                        BcSingles bcSingles) {
        String eidEncode = CookieUtils.getCookie(request, response, CookieConst.eidCookie);
        if (StrUtil.isEmpty(eidEncode)) {
            return;
        }
        String encodeEid = bcSinglesService.getEidDecode(eidEncode);
        bcSingles.setUserEid(encodeEid);
    }

    @PostMapping("login")
    public AjaxResp login(
            HttpServletRequest request,
            HttpServletResponse response,
            LoginRequest req) {
        BcUsers bcUsers = new BcUsers();
        String msg = "";
        if (req.getWay().equals("mobile")) {
            AjaxResp ajaxResp = new AjaxResp();
            String regRedisKey = RedisKey.bcSingleLoginRedisKey + req.getMobile();
            Object loginCode = redisUtils.get(regRedisKey);
            if (loginCode == null || !Convert.toStr(loginCode).equals(req.getSmsyzm())) {
                ajaxResp.setSuccess(false);
                ajaxResp.setMsg("手机验证码输入错误");
                return ajaxResp;
            }
            bcUsers.setMobile(req.getMobile());
        } else if (req.getWay().equals("password")) {
            msg = "用户名称或密码错误，请确认";
            bcUsers.setUsername(req.getUsername());
            bcUsers.setPassword(req.getPassword());
        } else if (!StrUtil.isEmpty(req.getOpenid())) {
            //如果是微信绑定登录
            msg = "微信未绑定";
            String openid = AESUtil.decrypt(req.getOpenid(), config.getOpenidSecret());
            Integer oId = Convert.toInt(openid, 0);
            bcUsers.setOpenid(oId);
        }
        BcUsers bcUsersResult = bcUsersService.loginByMobileEmail(bcUsers);
        AjaxResp ajaxResp = new AjaxResp();
        if (null == bcUsersResult) {
            ajaxResp.setSuccess(false);
            ajaxResp.setMsg(msg);
            return ajaxResp;
        }
        if (null == bcUsersResult.getId() || bcUsersResult.getId() <= 0) {
            ajaxResp.setSuccess(false);
            ajaxResp.setMsg(msg);
            return ajaxResp;
        }
        bcUsersService.login(request, response, bcUsersResult);
        //登录成功，如果有openid就绑定一下
        if (!StrUtil.isEmpty(req.getOpenid()) && !req.getOpenid().equals("null")) {
            String openid = AESUtil.decrypt(req.getOpenid(), config.getOpenidSecret());
            Integer oId = Convert.toInt(openid, 0);
            //判断一下，如果当前openid已经存在就不能再绑定了
            BcUsers bcUsersOpenId = new BcUsers();
            bcUsersOpenId.setOpenid(oId);
            if (bcUsersService.count(bcUsersOpenId) > 0) {
                ajaxResp.setSuccess(false);
                ajaxResp.setMsg("当前微信已经绑定过账户");
                return ajaxResp;
            }
            //绑定openid
            bcUsersOpenId.setId(bcUsersResult.getId());
            bcUsersOpenId.setOpenid(oId);
            bcUsersService.updateById(bcUsersOpenId);
        }
        ajaxResp.setCode(301);
        String targetUrl = "/m/center";
        if (StrUtil.isNotEmpty(req.getSource()) && req.getSource().contains("pc")) {
            targetUrl = "/center";
        }
        ajaxResp.setObj(targetUrl);
        ajaxResp.setMsg("登录成功");
        return ajaxResp;
    }

    /**
     * 发送手机短信验证码
     */
    @PostMapping("sendsmscode")
    public AjaxResp sendSmsCode(
            HttpServletRequest request,
            HttpServletResponse response,
            UserCodeRequest req) {
        AjaxResp ajaxResp = new AjaxResp();
        int count = bcUsersService.count(new BcUsers().setMobile(req.getMobile()));
        String reidsKey = "";
        SmsTemplatesEnum smsTemplatesEnum = null;
        if (req.getType().equals("reg")) {
            //如果是注册的时候需要判断一下是否存在，查询是否存在当前用户名称
            if (count > 0) {
                ajaxResp.setSuccess(false);
                ajaxResp.setMsg("当前手机已经注册了");
                return ajaxResp;
            }
            reidsKey = RedisKey.bcSingleRegRedisKey + req.getMobile();
            smsTemplatesEnum = SmsTemplatesEnum.REG_CODE;
        }
        if (req.getType().equals("login")) {
            //如果是登录查一下用户是否存在
            if (count <= 0) {
                ajaxResp.setSuccess(false);
                ajaxResp.setMsg("当前手机未注册");
                return ajaxResp;
            }
            reidsKey = RedisKey.bcSingleLoginRedisKey + req.getMobile();
            smsTemplatesEnum = SmsTemplatesEnum.LOGIN_CODE;

        }
        if (req.getType().equals("bind")) {
            //如果是注册的时候需要判断一下是否存在，查询是否存在当前用户名称
            if (count > 0) {
                ajaxResp.setSuccess(false);
                ajaxResp.setMsg("当前手机已经绑定了");
                return ajaxResp;
            }
            reidsKey = RedisKey.bcSingleBindRedisKey + req.getMobile();
            smsTemplatesEnum = SmsTemplatesEnum.MOBIIE_EDIT_CODE;
        }
        if (redisUtils.get(reidsKey) != null) {
            return ajaxResp;
        }
        JSONObject jsonObject = new JSONObject();
        int[] ints = NumberUtil.generateRandomNumber(0, 9, 6);
        String code = StrUtil.join("", ints);
        jsonObject.put("code", code);
        bcSmsUtil.sendSms(smsTemplatesEnum, Convert.toStr(req.getMobile()), jsonObject);
        //有效期30分钟
        redisUtils.set(reidsKey, code, 30, TimeUnit.MINUTES);
        return ajaxResp;
    }

    /**
     * 发送邮箱验证码
     */
    @PostMapping("sendemailcode")
    public AjaxResp sendEmailCode(
            HttpServletRequest request,
            HttpServletResponse response,
            UserCodeRequest req) {
        AjaxResp ajaxResp = new AjaxResp();
        int count = bcUsersService.count(new BcUsers().setEmail(req.getEmail()));
        String reidsKey = "";
        MailTemplatesEnum mailTemplatesEnum = null;
        if (req.getType().equals("reg")) {
            //如果是注册的时候需要判断一下是否存在，查询是否存在当前用户名称
            if (count > 0) {
                ajaxResp.setSuccess(false);
                ajaxResp.setMsg("当前邮箱已经注册了");
                return ajaxResp;
            }
            reidsKey = RedisKey.bcSingleRegRedisKey + req.getEmail();
            mailTemplatesEnum = MailTemplatesEnum.REG_CODE;
        }
        if (req.getType().equals("login")) {
            //如果是登录查一下用户是否存在
            if (count <= 0) {
                ajaxResp.setSuccess(false);
                ajaxResp.setMsg("当前邮箱未注册");
                return ajaxResp;
            }
            reidsKey = RedisKey.bcSingleLoginRedisKey + req.getEmail();
            mailTemplatesEnum = MailTemplatesEnum.LOGIN_CODE;
        }
        if (req.getType().equals("bind")) {
            //如果是注册的时候需要判断一下是否存在，查询是否存在当前用户名称
            if (count > 0) {
                ajaxResp.setSuccess(false);
                ajaxResp.setMsg("当前邮箱已经绑定了");
                return ajaxResp;
            }
            reidsKey = RedisKey.bcSingleBindRedisKey + req.getEmail();
            mailTemplatesEnum = MailTemplatesEnum.EMAIL_EDIT_CODE;
        }
        if (redisUtils.get(reidsKey) != null) {
            return ajaxResp;
        }
        JSONObject jsonObject = new JSONObject();
        int[] ints = NumberUtil.generateRandomNumber(0, 9, 6);
        String code = StrUtil.join("", ints);
        jsonObject.put("code", code);
        bcEmailUtil.sendEmail(mailTemplatesEnum, req.getEmail(), jsonObject);
        //有效期30分钟
        redisUtils.set(reidsKey, code, 30, TimeUnit.MINUTES);
        return ajaxResp;
    }

}
